#!/usr/bin/env python

import os, re

WHITESPACE_RE = re.compile('\s')

class HostsFile:
    def getHostsPath():
        if os.name == 'nt':
            out = 'c:\\windows\\system32\\drivers\\etc\\'
        else:
            out = '/etc/'
        return out
    getHostsPath = staticmethod(getHostsPath)

    def validateIP(address):
        return True
    validateIP = staticmethod(validateIP)

    def ip4or6(address):
        if HostsFile.validateIP(address):
            if len(address.split('.')):
                return 4
            else:
                return 6
        else:
            return False
    
    def __init__(self, path=False):
        if not path:
            self.path = "%shosts" % HostsFile.getHostsPath()
        else:
            self.path = path
        self.loadHosts()
        
    def loadHosts(self):
        self.addresses = dict()
        try:
            self.hosts = file(self.path, 'r')
            for line in self.hosts:
                if not line[0:1] == '#':
                    entry = WHITESPACE_RE.split(line.strip('\n'))
                    while 1:
                        try:
                            entry.remove('')
                        except(ValueError):
                            break
                    if len(entry) > 0:
                        self.addresses.update([(entry[0], entry[1:len(entry)])])
            self.hosts.close()
        except(IOError):
            self.addresses['127.0.0.1'] = ['localhost']
            self.addresses['::1']       = ['localhost']

    def getAddresses(self):
        return self.addresses.keys()

    def getHostsFor(self, address):
        return self.addresses[address]

    def checkAddressExists(self, address):
        return self.addresses.has_key(address)

    def newAddress(self, address):
        if HostsFile.validateIP(address):
            self.addresses[address] = []
            return True
        else:
            return False

    def replaceAddress(self, oldAddress, newAddress):
        if not HostsFile.validateIP(newAddress):
            return False
        try:
            self.addresses[newAddress] = self.addresses[oldAddress]
            del self.addresses[oldAddress]
            return True
        except(KeyError):
            return False

    def removeAddress(self, address):
        try:
            del self.addresses[address]
            return True
        except(KeyError):
            return False            

    def checkHostExists(self, host):
        exists = False
        for address in self.addresses:
            try:
                self.addresses[address].index(host)
                exists = True
                break
            except(ValueError):
                pass
        return exists

    def newHost(self, address, newHost):
        if self.checkHostExists(newHost) or newHost == '':
            return False
        self.addresses[address].append(newHost)
        return True

    def replaceHost(self, address, oldHost, newHost):
        if self.checkHostExists(newHost) or newHost == '':
            return False
        try:
            index = self.addresses[address].index(oldHost)
            self.addresses[address][index] = newHost
            return True
        except(ValueError):
            return False

    def removeHost(self, address, host):
        if self.checkHostExists(host):
            try:
                self.addresses[address].remove(host)
                return True
            except(ValueError):
                return False
        else:
            return False
    
    def save(self, saveas=False):
        if not (saveas == False):
            self.path = saveas

        self.hosts = file(self.path, 'w')
        for address in self.addresses.keys():
            if address != '':
                self.hosts.write('%s' % address)
                for host in self.addresses[address]:
                    if host != '':
                        self.hosts.write(' %s' % host)
                self.hosts.write('\n');
        self.hosts.close()
        
        self.loadHosts()

    def printAddresses(self):
        print self.addresses
